﻿using System;
using System.Collections.Generic;
using System.Data;
using Util.Database;

namespace AutoNZBLoader
{
    public class Request
    {
        private readonly string _Name;
        public string Name
        {
            get { return _Name; }
        }

        private readonly long _ShowId;
        public long ShowId
        {
            get { return _ShowId; }
        }

        private readonly long _Season;
        public long Season
        {
            get { return _Season; }
        }

        private readonly long _Episode;
        public long Episode
        {
            get { return _Episode; }
        }

        private readonly string _NameQuery;
        public string NameQuery
        {
            get { return _NameQuery; }
        }

        private readonly string _DetailsQuery;
        public string DetailsQuery
        {
            get { return _DetailsQuery; }
        }


        private Request(string name, long showId, long season, long episode, string nameQuery, string detailsQuery)
        {
            this._Name = name;
            this._ShowId = showId;
            this._Season = season;
            this._Episode = episode;
            this._NameQuery = nameQuery;
            this._DetailsQuery = detailsQuery;
        }

        public void MarkAsDownloaded(long season, long episode, string downloadAddress)
        {
            using (System.Data.IDbCommand cmd = DB.CreateCommand())
            {
                cmd.CommandText = "insert into downloaded(id_show, season, episode, downloaddate, downloadaddress) values(?, ?, ?, datetime(), ?)";
                IDbDataParameter par = cmd.CreateParameter();
                par.Value = ShowId;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = season;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = episode;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = downloadAddress;
                cmd.Parameters.Add(par);
                cmd.ExecuteNonQuery();

                if (this.Season != 0 && this.Episode != 0)
                {
                    cmd.Parameters.Clear();
                    cmd.CommandText = "delete from request where id_show=? and season=? and episode=?";
                    par = cmd.CreateParameter();
                    par.Value = ShowId;
                    cmd.Parameters.Add(par);
                    par = cmd.CreateParameter();
                    par.Value = this.Season;
                    cmd.Parameters.Add(par);
                    par = cmd.CreateParameter();
                    par.Value = this.Episode;
                    cmd.Parameters.Add(par);
                    cmd.ExecuteNonQuery();
                }
            }
        }

        public bool IsAlreadyDownloaded(long season, long episode)
        {
            using (System.Data.IDbCommand cmd = DB.CreateCommand())
            {
                cmd.CommandText = "select count(*) from downloaded where id_show=? and season=? and episode=?";
                IDbDataParameter par = cmd.CreateParameter();
                par.Value = ShowId;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = season;
                cmd.Parameters.Add(par);
                par = cmd.CreateParameter();
                par.Value = episode;
                cmd.Parameters.Add(par);
                return ((long)cmd.ExecuteScalar()) != 0;
            }
        }

        public bool Matches(FeedItem feedItem)
        {
            Util.TitleParser.Result r = Util.TitleParser.Parser.ParseTitle(feedItem.Title);
            if ((r != null) && (feedItem.Episode == Episode || Episode == 0) && (feedItem.Season == Season || Season == 0))
            {
                if (MatchQuery(NameQuery, r.Name) && MatchQuery(DetailsQuery, r.Details))
                {
                    return true;
                }
            }

            return false;
        }

        private static bool MatchQuery(string qry, string str)
        {
            if (qry.Trim().Length == 0)
            {
                return true;
            }

            try
            {
                Util.QueryParser.Token.IToken t = Util.QueryParser.Parser.BuildTokenTree(qry);
                return t.Evaluate(str);
            }
            catch (Util.QueryParser.ParserException)
            {
                return false;
            }
        }

        private static IList<Request> _Requests;
        public static IList<Request> getRequests()
        {
            if (_Requests == null)
            {
                List<Request> lst = new List<Request>();

                using (System.Data.IDbCommand cmd = DB.CreateCommand())
                {
                    cmd.CommandText = "select show.name showname, request.id_show id_show, request.season season, request.episode episode, show.namequery namequery, show.detailsquery detailsquery from request, show where show.id = request.id_show";
                    using (IDataReader dr = cmd.ExecuteReader())
                    {
                        while (dr.Read())
                        {
                            try
                            {
                                lst.Add(new Request(dr["SHOWNAME"].ToString(), (long)dr["ID_SHOW"], (long)dr["SEASON"], (long)dr["EPISODE"], dr["NAMEQUERY"].ToString(), dr["DETAILSQUERY"].ToString()));
                            }
                            catch (System.Data.Common.DbException) { }
                            catch (InvalidCastException) { }
                        }
                    }
                }
                _Requests = new System.Collections.ObjectModel.ReadOnlyCollection<Request>(lst);
            }
            return _Requests;
        }
    }
}
